package fem2.strategies;

import inf.jlinalg.ArrayVector;
import inf.jlinalg.SolveFailedException;

import java.util.Arrays;

import fem2.Debugger;
import fem2.Model;
import fem2.enu.EchoLevelType;
import fem2.enu.MassMatrixType;
import fem2.jlinalg.Solver;

public abstract class ExplicitTimeIntegrationStrategy extends ImplicitTimeIntegrationStrategy {

	public ExplicitTimeIntegrationStrategy(Model m, MassMatrixType massType, double alpha1,
			double alpha2) {
		super(m, massType, alpha1, alpha2);
	}

	@Override
	public boolean iterationFinished(Solver leftHandSideSolver, ArrayVector rightHandSide,
			ArrayVector u) {

		leftHandSideSolver.initialize();
		Arrays.fill(rightHandSide.getValues(), 0);
		this.assembleEffectiveSystem(leftHandSideSolver.getA(), rightHandSide);

		if (getEchoLevel().contain(EchoLevelType.AUX2)) {
			Debugger.watch("keff = ", leftHandSideSolver.getA());
			Debugger.watch("reff = ", rightHandSide);
		}

		/*
		 * solve
		 */
		try {
			leftHandSideSolver.solve(rightHandSide.getValues());
		} catch (SolveFailedException e) {
			throw new Error("Solve failed");
		}

		/*
		 * update solution: update uHat, udHat, uddHat
		 */
		this.updateSolution(rightHandSide);

		/*
		 * update model material
		 */
		model.setX(t, uHat.getValues());
		model.FinalizeNonlinearIteration();

		if (getEchoLevel().contain(EchoLevelType.DEBUG)) {
			Debugger.watch("uHat = ", uHat);
		}

		/*
		 * stop the iteration loop
		 */
		return true;
	}

}
